package org.smarthings.http;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.smarthings.Message;
import org.smarthings.MessageBroker;
import org.smarthings.Response;
import org.smarthings.Utils;

public class HttpServletImpl extends HttpServlet {
	private static final long serialVersionUID = 2294746641245105126L;
	private static final MessageBroker broker = MessageBroker.getInstance();

	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		String uri = Utils.normalizeUri(req.getRequestURI());
		Message message = broker.get(uri, req.getHeader("Accept"));
		if (message == null || message.getResponseCode() == 204) {
			resp.setStatus(204);
			return;
		}
		resp.setStatus(message.getResponseCode());
		resp.setContentType(message.getContentType());

		OutputStream os = resp.getOutputStream();
		os.write(message == null ? "".getBytes() : message.getPayload());
		os.flush();
		os.close();
	}

	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		InputStream is = req.getInputStream();
		byte[] payload = IOUtils.toByteArray(is);
		is.close();

		String uri = Utils.normalizeUri(req.getRequestURI());
		Message message = Message.createSender(payload, HttpFactory.PROTOCOL, uri, req.getContentType(),
				req.getHeader("Accept"), req.getMethod());
		Response response = broker.post(message);
		resp.setStatus(response.getCode());

		Map<String, List<String>> headers = response.getHeaders();
		if (headers != null) {
			for (String header : headers.keySet()) {
				if (header != null) {
					String value = headers.get(header).listIterator().next();
					if (value != null) {
						resp.setHeader(header, value);
					}
				}
			}
		}

		if (response.getPayload() != null) {
			OutputStream os = resp.getOutputStream();
			os.write(response.getPayload());
			os.flush();
			os.close();
		}
	}

	protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doPost(req, resp);
	}

	protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doPost(req, resp);
	}
}
